package data.join.com.service;

import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.google.gson.Gson;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.HashMap;

import data.join.com.application.EventMessage;
import data.join.com.carapi.ApiPref;
import data.join.com.carapi.WebSocketServer;
import data.join.com.database.bean.CommandBean;
import data.join.com.database.bean.CommandPref;
import data.join.com.database.bean.FileNameSync;
import data.join.com.database.bean.PhotoBean;
import data.join.com.database.bean.PhotoPref;
import data.join.com.database.bean.UpdateBean;
import data.join.com.database.bean.UpdatePref;
import data.join.com.media.AppUpdateThread;
import data.join.com.media.CommandHandleThread;
import data.join.com.media.FileNameSyncThread;
import data.join.com.media.PhotoHandleThread;
import data.join.com.media.UploadLogThread;
import data.join.com.media.VideoScannerThread;
import data.join.com.media.VideoUploadThread;
import data.join.com.network.RetrofitManager;
import data.join.com.network.gson.UpdateCommandRequest;
import data.join.com.socket.AliMqttClient;
import data.join.com.media.DeviceRegisterThread;
import data.join.com.socket.MqttCommand;
import data.join.com.socket.OfflineAlarmConnect;
import data.join.com.utils.MyLog;
import data.join.com.utils.NetworkUtils;
import data.join.com.utils.QuickShPref;
import retrofit2.Call;

/**
 * Created by Administrator on 2017/9/18.
 */

public class MainService extends BaseService{

    private static String TAG = MainService.class.getSimpleName();

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void startWork() {

        QuickShPref.getInstance().putValueObject(QuickShPref.DeviceImei,getDeviceIMEI());

        ApiPref.getInstance(this).initConfig();

        DeviceRegisterThread.getInstance(this).start();

        VideoScannerThread.getInstance(this).start();

        OfflineAlarmConnect.getInstance(this).start();

        WebSocketServer.getInstance().start();
    }

    private void doStartWork(){

        AliMqttClient.getInstance(this).connectServer();

        FileNameSyncThread.getInstance(this).start();

        VideoUploadThread.getInstance(this).start();

        CommandHandleThread.getInstance(this).start();

        AppUpdateThread.getInstance(this).start();

        PhotoHandleThread.getInstance(this).start();
    }

    public static void startMainService(Context context){
        context.startService(new Intent(context, MainService.class));
    }

    public String getDeviceIMEI() {
        TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
        return tm.getDeviceId();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventMessage event) {
        if (event.what == EventMessage.NEW_MQTT_COMMAND) {
            insertCommand(event);
        }else if(event.what == EventMessage.DEVICES_REGISTER_SUCCESS){
            doStartWork();
        }else if(event.what == EventMessage.NEW_FILE_CREATE){
            FileNameSyncThread.getInstance(this).wakeUp();
        }else if(event.what == EventMessage.MQTT_SUB_SUCCESS){
            CommandHandleThread.getInstance(this).wakeUp();
        }
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEventBackgroundThread(EventMessage event) {
        if (event.what == EventMessage.MEDIA_FILE_ADD) {
            VideoScannerThread.getInstance(this).addVideoFile(event.msg);
            FileNameSyncThread.getInstance(this).wakeUp();
        }else if(event.what == EventMessage.MEDIA_FILE_REMOVE){
            VideoScannerThread.getInstance(this).removeVideoFile(event.msg);
        }else if(event.what == EventMessage.MEDIA_FILE_LOCK){
            VideoScannerThread.getInstance(this).addVideoFile(event.msg);
            VideoUploadThread.getInstance(this).wakeUp();
        }
    }

    private void insertCommand(EventMessage event){
        MqttCommand mqttCommand = null;
        try {
            mqttCommand = new Gson().fromJson(event.msg, MqttCommand.class);
        }catch (Exception e){
            e.printStackTrace();
        }
        if(mqttCommand == null || TextUtils.isEmpty(mqttCommand.command_id)){
            MyLog.E(TAG,"mqttCommand or command_id is null");
        }else if(MqttCommand.TYPE_UPLOAD_VIDEO.equals(mqttCommand.type)){
            if(CommandPref.getInstance().existCommandById(mqttCommand.command_id)){
                MyLog.E(TAG, "exist Command Id:"+mqttCommand.command_id);
            }else {
                CommandBean commandBean = new CommandBean();
                commandBean.type = mqttCommand.type;
                commandBean.commandId = mqttCommand.command_id;
                commandBean.mediaId = mqttCommand.resource_id;
                commandBean.handleState = CommandPref.HANDLE_STATE_CREATE;
                CommandPref.getInstance().insertCommandBean(commandBean);
                CommandHandleThread.getInstance(this).wakeUp();
                MyLog.D(TAG, "insertCommand mqttCommand insert");
            }
        }else if(MqttCommand.TYPE_UPGRADE_APP.equals(mqttCommand.type)){

            if(UpdatePref.getInstance().existCommandById(mqttCommand.command_id)){
                MyLog.E(TAG, "exist Command Id:"+mqttCommand.command_id);
            }else {
                UpdateBean updateBean = new UpdateBean();
                updateBean.setCloudPath(mqttCommand.url);
                updateBean.setVersion(mqttCommand.upgrade_version);
                updateBean.setUpdateState(UpdatePref.UPDATE_CREATE);
                updateBean.setCommandId(mqttCommand.command_id);
                UpdatePref.getInstance().insertUpdate(updateBean);
                AppUpdateThread.getInstance(this).wakeUp();
                MyLog.D(TAG, "insertUpdate mqttCommand insert");
            }
        }else if(MqttCommand.TYPE_CONFIG_APP.equals(mqttCommand.type)){
            if("emergency_video_record".equals(mqttCommand.key)){
                if("enable".equals(mqttCommand.value)){
                    QuickShPref.getInstance().putValueObject(QuickShPref.LockVideoEnable,true);
                    VideoUploadThread.getInstance(this).wakeUp();
                    MyLog.D(TAG,"set LockVideoEnable True");
                }else if("disable".equals(mqttCommand.value)){
                    QuickShPref.getInstance().putValueObject(QuickShPref.LockVideoEnable,false);
                    MyLog.D(TAG,"set LockVideoEnable False");
                }
                updateAppConfigCommand(mqttCommand.command_id);
            }
        }else if(MqttCommand.TYPE_UPLOAD_LOG.equals(mqttCommand.type)){
            new UploadLogThread(this,mqttCommand.command_id).start();
        }else if(MqttCommand.TYPE_TAKE_PHOTO.equals(mqttCommand.type)){
            PhotoBean photoBean = new PhotoBean();
            photoBean.commandId = mqttCommand.command_id;
            photoBean.type = mqttCommand.type;
            photoBean.handleState = PhotoPref.HANDLE_STATE_CREATE;
            PhotoPref.getInstance().insertPhotoBean(photoBean);
            PhotoHandleThread.getInstance(this).wakeUp();
        }else{
            MyLog.D(TAG, "unknow command type");
        }
    }

    public static boolean isNetWorkConnect(Context context,String tag){
        boolean ret;

        boolean net = NetworkUtils.isNetWorkConnect(context);

        boolean mqtt =  AliMqttClient.getInstance(context).isConnected();

        ret = net && mqtt;

        MyLog.D(tag,"isNetWorkConnect ret="+ret+",net="+net+",mqtt="+mqtt);

        return ret;
    }

    private boolean updateAppConfigCommand(String commandId){
        boolean ret = false;

        UpdateCommandRequest commandRequest = new UpdateCommandRequest();
        HashMap<String,String> content = new HashMap<>();

        content.put("command_type",MqttCommand.TYPE_CONFIG_APP);
        content.put("status","client_received");

        commandRequest.content = content;

        Call<Object> objectCall = RetrofitManager.getApiService().updateCommand(commandId,RetrofitManager.getBodyByJson(commandRequest));

        try {
            ret = objectCall.execute().isSuccessful();

            if(!ret){
                objectCall = RetrofitManager.getApiService().updateCommand(commandId,RetrofitManager.getBodyByJson(commandRequest));
                ret = objectCall.execute().isSuccessful();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        MyLog.D(TAG,"updateAppConfigCommand ret = "+ret);

        return ret;
    }

}
